{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"contentcontainer med left\" style=\"margin-left: -50px;\">\n",
    "<dl class=\"dl-horizontal\">\n",
    "  <dt>Title</dt> <dd> HeatMap Element (radial) </dd>\n",
    "  <dt>Dependencies</dt> <dd>Bokeh</dd>\n",
    "  <dt>Backends</dt> <dd><a href='./RadialHeatMap.ipynb'>Bokeh</a></dd> <dd><a href='../matplotlib/RadialHeatMap.ipynb'>Matplotlib</a></dd>\n",
    "</dl>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import holoviews as hv\n",
    "from holoviews import opts\n",
    "hv.extension('bokeh')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A radial ``HeatMap`` is well suited to discover **periodic patterns** and **trends** in **time series** data and other cyclic variables. A radial HeatMap can be plotted simply by activating the ``radial`` plot option on the ``HeatMap`` element.\n",
    "\n",
    "To start, let us set the default radial `HeatMap` options by both enabling hover and setting the size:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "opts.defaults(opts.HeatMap(radial=True, width=800, height=800, tools=[\"hover\"]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we will create a synthetic dataset of a value varying by the hour of the day and day of the week:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "days = 31\n",
    "hours = 24\n",
    "size = days*hours\n",
    "\n",
    "def generate_hourly_periodic_data(x):\n",
    "    periodic_weekly = np.sin(x*2*np.pi / (24*7))\n",
    "    periodic_daily = np.sin(x*2*np.pi / 24)\n",
    "    noise = np.random.random(size=x.size)  \n",
    "    return periodic_weekly + periodic_daily + noise\n",
    "\n",
    "x = np.linspace(0, size, size)\n",
    "y = generate_hourly_periodic_data(x)\n",
    "\n",
    "date_index = pd.date_range(start=\"2017-10-01\", freq=\"h\", periods=size)\n",
    "kdim_segment = date_index.strftime(\"%H:%M\")\n",
    "kdim_annular = date_index.strftime(\"%A %d\")\n",
    "\n",
    "df = pd.DataFrame({\"values\": y, \"hour\": kdim_segment, \"day\": kdim_annular}, index=date_index)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As with a regular ``HeatMap`` the data should consist of two index variables or key dimensions and one or more value dimensions. Here we declare the 'hour' and 'day' as the key dimensions. For a radial HeatMap to make sense the first key dimension, which will correspond to the radial axis, should be periodic. Here the variable is 'hour', starting at midnight at the top:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hv.HeatMap(df, [\"hour\", \"day\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The resulting plot is quite bare so we may want to customize it, there are a number of things we can do to make the plot clearer:\n",
    "\n",
    "1. Increase the inner padding with the ``radius_inner`` option.\n",
    "2. Increase the number of ticks along the radial axis using ``xticks``\n",
    "3. Add radial separator marks with the ``xmarks`` option.\n",
    "4. Change the colormap using the ``cmap`` style option."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "heatmap = hv.HeatMap(df, [\"hour\", \"day\"])\n",
    "heatmap.opts(opts.HeatMap(cmap='viridis', radial=True, xmarks=8, ymarks=4))"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
